# Copyright (c) 2021 Presto Labs Pte. Ltd.
# Author: xguo

import json
import os
import pathlib
import sys
import tempfile

LOG_PRIVATE_MESSAGE = False

def get_mea(uniq_product):
  market, exchange, product = uniq_product.split(':', 2)
  me = f'{market}.{exchange}'

  if me == 'Spot.Binance':
    return me + '.v1'

  if me == 'Futures.Binance':
    if 'USDT' in product:
      return me + '.v1'
    else:
      return me + '.v1-delivery'

  if me == 'Futures.Prex':
    return me + '.v1'


  raise(Exception('Unknown product'))


def get_norm_product(uniq_product):
  return uniq_product.split(':', 2)[2]


def get_recipe(mea_str):
  mea_str = mea_str.replace('.', '_').lower()
  start_find = False
  has_realtime = False
  has_snapshot = False
  has_incremental = False
  with open('data/coin2/feed/subscribers.toml') as f:
    for line in f.readlines():
      if mea_str in line:
        start_find = True
      if start_find:
        if "recipes.realtime " in line:
          has_realtime = True
        if "recipes.snapshot " in line:
          has_snapshot = True
        if "recipes.incremental " in line:
          has_incremental = True
        if line == "" or line == "\r" or line == "\n":
          break
  if has_realtime:
    return "realtime"
  if has_snapshot:
    return "snapshot"
  return "incremental"


class Converter(object):
  def __init__(self, exchange):
    self.app_config = {
      'feed': {'exchanges': {}},
      'order': {'exchanges': {}},
      'log': None,
      'strategy': None,
    }
    self.app_relpath = "bazel-bin/cc/appcoin2/strategy/umm/umm_runner"

    config_dir = pathlib.Path('cc/experimental/xguo/pilot')
    config_dir = config_dir.joinpath(exchange)
    config_path = config_dir.joinpath('umm_config.json')
    self.config = json.loads(config_path.read_text())
    self.config_path = config_path.as_posix()

  @property
  def feed(self):
    return self.app_config['feed']

  @property
  def order(self):
    return self.app_config['order']

  def init_log(self):
    self.app_config["log"] = {
        "health_report_period_ns": 30000000000,
    }

  def init_strategy(self):
    config = self.config
    strategy_name = config['strategy_name']
    strategy_group = config['strategy_group']
    self.app_config["strategy"] = {
        "strategy_group": strategy_group,
        "strategy_name": strategy_name,
    }

  def init_feed(self, mea):
    if mea in self.feed["exchanges"]:
      return

    config = {}
    config["mea"] = mea
    config["type"] = "FEED_SYSTEM_TYPE_LIVE"
    config["websocket"] = {"num_workers": 1}
    config["products"] = {"norms": []}
    config["recipe"] = get_recipe(mea)
    self.feed["exchanges"][mea] = config

  def init_order(self, mea):
    exch = mea.split('.')[1]
    if exch in self.order["exchanges"]:
      return

    path = self.config['key_filepath']
    config_dir_path = pathlib.Path.home().joinpath('config')
    key_path = config_dir_path.joinpath(path).as_posix()

    config = {}
    config["mea"] = mea
    config["type"] = "ORDER_SYSTEM_TYPE_LIVE_OG"
    config["products"] = {"norms": []}
    config["order_gateway_config"] = {"log_private_exchange_message": LOG_PRIVATE_MESSAGE}
    config["connection_config"] = {"key_filepath": key_path}
    self.order["exchanges"][exch] = config

  def add_feed_product(self, uniq_product):
    mea = get_mea(uniq_product)
    self.init_feed(mea)
    norm_prod = self.feed["exchanges"][mea]["products"]["norms"]
    norm_prod.append(get_norm_product(uniq_product))

  def add_order_product(self, uniq_product):
    mea = get_mea(uniq_product)
    self.init_order(mea)
    exch = mea.split('.')[1]
    norm_prod = self.order["exchanges"][exch]["products"]["norms"]
    norm_prod.append(get_norm_product(uniq_product))

  def convert_to_app_config(self):
    for config in self.config['subconfig'].values():
      self.add_feed_product(config['trade_symbol'])
      self.add_feed_product(config['ref_symbol'])
      self.add_order_product(config['trade_symbol'])

  def run(self):
    self.init_log();
    self.init_strategy()
    self.convert_to_app_config()

    filename = tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".json", prefix="umm.")
    filename.write(json.dumps(self.app_config, indent=2))
    cmd_line = f"{self.app_relpath} --driver={filename.name} --config={self.config_path} --logtostderr"
    print(json.dumps(self.app_config, indent=2))
    print(cmd_line)


def main(argv):
  converter = Converter(argv[1])
  converter.run()


if __name__ == '__main__':
  sys.exit(main(sys.argv))
